package com.cc.utils;

import com.cc.pojo.tablestruct.LibaryProperties;
import com.cc.pojo.tablestruct.TableStruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author c.c
 * @since 2022/8/11
 * 读取该数据库下所有表格的结构数据
 */
@Slf4j
public class LibaryReadTable {
  static String dataBaseName = JDBCUtils.getDataBaseName();
  static Connection conn = JDBCUtils.getConnection();


  private static List<TableStruct> readColumn() throws SQLException {
    String sql = "select * from information_schema.COLUMNS WHERE TABLE_SCHEMA = " + dataBaseName;
    conn.setAutoCommit(false);
    PreparedStatement preparedStatement = conn.prepareStatement(sql);
    ResultSet resultSet = preparedStatement.executeQuery();

    ArrayList<TableStruct> resultSets = new ArrayList<TableStruct>();
    while (resultSet.next()) {
      TableStruct tableProperties = new TableStruct();
      tableProperties.setTableSchema(resultSet.getString("TABLE_SCHEMA"));
      tableProperties.setTableName(resultSet.getString("TABLE_NAME"));
      tableProperties.setColumnName(resultSet.getString("COLUMN_NAME"));
      tableProperties.setDataType(resultSet.getString("DATA_TYPE"));
      tableProperties.setColumnType(resultSet.getString("COLUMN_TYPE"));

      //设置字符长度
      if ("varchar".equals(tableProperties.getDataType())
        || "tinytext".equals(tableProperties.getDataType())
        || "char".equals(tableProperties.getDataType())
        || "varbinary".equals(tableProperties.getDataType())
        || "text".equals(tableProperties.getDataType())
        || "longtext".equals(tableProperties.getDataType())) {
        tableProperties.setCharacterMaximumLength(resultSet.getString("CHARACTER_MAXIMUM_LENGTH"));
      } else if ("int".equals(tableProperties.getDataType()) || "bigint".equals(tableProperties.getDataType())) {
        String columnType = tableProperties.getColumnType();
        if (columnType.contains("(") || columnType.contains(")")) {
          tableProperties.setCharacterMaximumLength(tableProperties.getColumnType().substring(columnType.indexOf("(") + 1, columnType.indexOf(")")));
        } else {
          tableProperties.setCharacterMaximumLength(resultSet.getString("NUMERIC_SCALE"));
        }
      } else {
        String front = resultSet.getString("NUMERIC_PRECISION");
        String back = resultSet.getString("NUMERIC_SCALE");
        if (back != null && !"0".equals(back)) {
          tableProperties.setCharacterMaximumLength(front + "," + back);
        } else {
          tableProperties.setCharacterMaximumLength(front);
        }
      }


      tableProperties.setColumnComment(resultSet.getString("COLUMN_COMMENT"));
      resultSets.add(tableProperties);
    }

    preparedStatement.close();
    return resultSets;
  }


  /**
   * 读取该库中有哪些表
   * * @author sosmcc
   */
  private static List<LibaryProperties> readlibary() throws SQLException {

    String sql = "SELECT * from information_schema.TABLES where TABLE_SCHEMA = " + dataBaseName;
    conn.setAutoCommit(false);
    PreparedStatement preparedStatement = conn.prepareStatement(sql);
    ResultSet resultSet = preparedStatement.executeQuery();


    List<LibaryProperties> libaryProperties = new ArrayList<>();
    while (resultSet.next()) {
      LibaryProperties temp = new LibaryProperties();
      temp.setTableName(resultSet.getString("TABLE_NAME"));
      temp.setTableComment(resultSet.getString("TABLE_COMMENT") == null ? null : resultSet.getString("TABLE_COMMENT"));
      libaryProperties.add(temp);
    }
    preparedStatement.close();
    return libaryProperties;
  }

  /**
   * 只获取库信息
   *
   * @return List<LibaryProperties>
   * @author C.c
   * @since 2023-04-03 17:28
   **/
  public static List<LibaryProperties> getReadlibary() throws SQLException {
    List<LibaryProperties> readlibary = readlibary();
    conn.close();
    return readlibary;
  }

  public static List<TableStruct> getReadColumn() throws SQLException {
    List<TableStruct> tableStructs = readColumn();
    conn.close();
    return tableStructs;
  }

  /**
   * 获取库信息和表结构
   *
   * @param
   * @return
   * @author C.c
   * @since 2023-04-04 09:43
   **/
  public static List<LibaryProperties> readAlllibaryAndTableStruct() throws SQLException {
    List<LibaryProperties> result;
    try {
      result = readlibary();
      List<TableStruct> tableStructs = readColumn();

      //先转换成map
      result.stream().map(libaryProperties -> Pair.of(libaryProperties.getTableName(), libaryProperties))
        //遍历转换后的map
        .forEach(map -> {
          //把map和数据库字段进行对应
          tableStructs.stream().collect(Collectors.groupingBy(TableStruct::getTableName)).forEach((k, v) -> {
            if (map.getLeft().equalsIgnoreCase(k)) {
              if (k.equals("vtprocdetaildept")) {
                log.info("我进来了");
              }
              if (v != null && !v.isEmpty()) {
                map.getRight().setTableStructs(v);
              } else {
                log.info("表" + k + "的数据为null" + "{" + v + "}");

              }
            }
          });

        });
    } catch (SQLException e) {
      throw new RuntimeException(e);
    }
//    finally {
//      conn.close();
//    }
    return result;
  }

  public static void reload() {
    try {
      JDBCUtils.reload();
    } catch (SQLException e) {
      throw new RuntimeException(e);
    }
    dataBaseName = JDBCUtils.getDataBaseName();
    conn = JDBCUtils.getConnection();
  }
}